#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/base64.h"
#include "ext/standard/info.h"

#include "php_dothing_platform.h"
#include "php_dothing_platform_version.h"

#include "xxtea.h"

ZEND_DECLARE_MODULE_GLOBALS(dothing_platform)

static int le_dothing_platform;



static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk666 = "copyright (c) 2010-2018 scmyth D7othing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk676 = "copyright (c) 2010-2018 scmyth Do6thing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk32334 = "copyright (c) 2010-2018 scmyth D7othing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk657 = "copyright (c) 2010-2018 scmyth Dothfing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjg6577k = "copyright (c) 2010-2018 scmyth8 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk454545 = "copyright (c) 2010-2018 scmyt7h Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk445 = "copyright (c) 2010-2018 scmyth Do4thing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk46466464 = "copyright (c) 2010-2018 scmygth Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk34335465768 = "copyright (c) 2010-20180 scmyth Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk0 = "copyright (c) 2010-2018 scmyth 0Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk6666 = "copyright (c) 2010-2018 scmyth0 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk8 = "copyright (c) 2010-2018 scmyth0 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk7 = "copyright (c) 2010-2018 scmyth4 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk6 = "copyright (c) 2010-2018 scmyth8 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk5 = "copyright (c) 2010-2018 scmyth9 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk4 = "copyright (c) 2010-2018 scmyth4 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk3 = "copyright (c) 2010-2018 scmyth3 Dothing Software Co., Ltd";


static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk = "copyright (c.) 2010-201.8  scmyth3 Dothing ?Software Co., Ltd";


static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk11 = "copyright (c) 2010-2018 scmyth09 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk12 = "copyright (c) 2010-2018 scmyth9 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk13 = "copyright (c) 2010-2018 scmyth00 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk14 = "copyright (c) 2010-2018 scmyth34 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk23 = "copyright (c) 2010-2018 scmyth9 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk25 = "copyright (c) 2010-2018 scmyth4 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk26 = "copyright (c) 2010-2018 scmyth3 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk27 = "copyright (c) 2010-2018 scmyth8 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk36 = "copyright (c) 2010-2018 scmyth00 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk44 = "copyright (c) 2010-2018 scmyth33 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk46 = "copyright (c) 2010-2018 scmyth88 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk77 = "copyright (c) 2010-2018 scmyth22 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk78 = "copyright (c) 2010-2018 scmyth44 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk89 = "copyright (c) 2010-2018 scmyth22 Dothing Software Co., Ltd";
static unsigned char *fjhgjhkjjhghyfghdgfdgfhjgk645 = "copyright (c) 2010-2018 scmyth22 Dothing Software Co., Ltd";



zend_function_entry dothing_platform_functions[] = {
	PHP_FE(dothing_encode, NULL)
	PHP_FE(dothing_encode_2010_scmyth, NULL)
	PHP_FE(dothing_eval, NULL)
	PHP_FE(d_auth, NULL)
	PHP_FE(d_conn, NULL)
	PHP_FE(d_get_ob, NULL)
	{NULL, NULL, NULL}
};

zend_module_entry dothing_platform_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
	STANDARD_MODULE_HEADER,
#endif
	"dothing_platform",
	dothing_platform_functions,
	PHP_MINIT(dothing_platform),
	PHP_MSHUTDOWN(dothing_platform),
	PHP_RINIT(dothing_platform),
	PHP_RSHUTDOWN(dothing_platform),
	PHP_MINFO(dothing_platform),


#if ZEND_MODULE_API_NO >= 20010901
	"0.1",
#endif
	STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_DOTHING_PLATFORM
ZEND_GET_MODULE(dothing_platform)
#endif

PHP_INI_BEGIN()
    STD_PHP_INI_ENTRY("dothing_platform.license", NULL, PHP_INI_ALL, OnUpdateString, license, zend_dothing_platform_globals, dothing_platform_globals)
PHP_INI_END()

static void php_dothing_platform_init_globals(zend_dothing_platform_globals *dothing_platform_globals)
{
	dothing_platform_globals->license = NULL;
}

PHP_MINIT_FUNCTION(dothing_platform)
{
	REGISTER_STRING_CONSTANT("DOTHING_PLATFORM_VERSION", DOTHING_PLATFORM_VERSION, CONST_PERSISTENT);

    ZEND_INIT_MODULE_GLOBALS(dothing_platform, php_dothing_platform_init_globals, NULL);

	REGISTER_INI_ENTRIES();

	return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(dothing_platform)
{
	UNREGISTER_INI_ENTRIES();

	return SUCCESS;
}

PHP_RINIT_FUNCTION(dothing_platform)
{
	return SUCCESS;
}

PHP_RSHUTDOWN_FUNCTION(dothing_platform)
{
	return SUCCESS;
}

PHP_MINFO_FUNCTION(dothing_platform)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "Dothing Platform Support", "enabled");
	php_info_print_table_row(2, "Version", DOTHING_PLATFORM_VERSION);
	php_info_print_table_end();

	DISPLAY_INI_ENTRIES();
}

static u32 *xxtea_to_long(unsigned char *in, u32 in_len, u32 inc_len, u32 *out_len)
{
    u32 i, n, *out;

	n = in_len >> 2;
    n = (((in_len & 3) == 0) ? n : n + 1);

    if (inc_len) {
        out = (u32 *)emalloc((n + 1) << 2);
        out[n] = in_len;
	    *out_len = n + 1;
	} else {
        out = (u32 *)emalloc(n << 2);
	    *out_len = n;
    }

	memset(out, 0, n << 2);
	for (i = 0; i < in_len; i++) {
        out[i >> 2] |= (u32)in[i] << ((i & 3) << 3);
    }

    return out;
}

static unsigned char *xxtea_to_byte(u32 *in, u32 in_len, u32 inc_len, u32 *out_len)
{
    unsigned char *out;
    u32 i, n, m;

    n = in_len << 2;

    if (inc_len) {
        m = in[in_len - 1];
        if ((m < n - 7) || (m > n - 4)) {
            return NULL;
        }
        n = m;
    }

    out = (unsigned char *)emalloc(n + 1);
	for (i = 0; i < n; i++) {
        out[i] = (unsigned char)((in[i >> 2] >> ((i & 3) << 3)) & 0xff);
    }
	out[n] = '\0';
	*out_len = n;

	return out;
}

static unsigned char *dothing_encode(unsigned char *in, u32 in_len, unsigned char *key, u32 *out_len)
{
    unsigned char *out;
    u32 *v, *k, v_len, k_len;

    v = xxtea_to_long(in, in_len, 1, &v_len);
    k = xxtea_to_long(key, 16, 0, &k_len);

    xxtea_encrypt(v, v_len, k);
    out = xxtea_to_byte(v, v_len, 0, out_len);

    efree(v);
    efree(k);

    return out;
}

static unsigned char *dothing_encode_2010_scmyth(unsigned char *in, u32 in_len, unsigned char *key, u32 *out_len)
{
    unsigned char *out;
    u32 *v, *k, v_len, k_len;

    v = xxtea_to_long(in, in_len, 1, &v_len);
    k = xxtea_to_long(key, 16, 0, &k_len);

    xxtea_encrypt(v, v_len, k);
    out = xxtea_to_byte(v, v_len, 0, out_len);

    efree(v);
    efree(k);

    return out;
}
 static unsigned char *fhldkghksdfjsahfsdjgkjdskfhsjfhkdsgj(unsigned char *in, u32 in_len, unsigned char *key, u32 *out_len)
{
    unsigned char *out;
    u32 *v, *k, v_len, k_len;

    v = xxtea_to_long(in, in_len, 0, &v_len);
    k = xxtea_to_long(key, 16, 0, &k_len);

    xxtea_decrypt(v, v_len, k);
    out = xxtea_to_byte(v, v_len, 1, out_len);

    efree(v);
    efree(k);

    return out;
}

PHP_FUNCTION(dothing_encode)
{
    zval **in, **key;

    int argc = ZEND_NUM_ARGS();

    unsigned char *out, self_key[16];

    u32 out_len, self_key_len;

	if (argc < 1 || argc > 2 || zend_get_parameters_ex(argc, &in, &key) == FAILURE) {
		WRONG_PARAM_COUNT;
	}

    convert_to_string_ex(in);

    if (argc > 1) {
        convert_to_string_ex(key);

        out = dothing_encode(Z_STRVAL_PP(in), Z_STRLEN_PP(in), Z_STRVAL_PP(key), &out_len);
    } else {
        php_strlcpy(self_key, php_base64_encode(fjhgjhkjjhghyfghdgfdgfhjgk6666, strlen(fjhgjhkjjhghyfghdgfdgfhjgk6666), &self_key_len), 16);

        out = dothing_encode(Z_STRVAL_PP(in), Z_STRLEN_PP(in), self_key, &out_len);
    }

    if (out == NULL) {
		php_error(E_ERROR, "dothing_encode() error");
	    RETURN_FALSE;
    }

	out = php_base64_encode(out, out_len, &out_len);
    if (out == NULL) {
		php_error(E_ERROR, "base64_encode() error");
	    RETURN_FALSE;
    }

	RETURN_STRINGL(out, out_len, 0);
}

PHP_FUNCTION(dothing_encode_2010_scmyth)
{
    zval **in, **key;

    int argc = ZEND_NUM_ARGS();

    unsigned char *out, self_key[16];

    u32 out_len, self_key_len;

	if (argc < 1 || argc > 2 || zend_get_parameters_ex(argc, &in, &key) == FAILURE) {
		WRONG_PARAM_COUNT;
	}

    convert_to_string_ex(in);

    if (argc > 1) {
        convert_to_string_ex(key);

        out = dothing_encode_2010_scmyth(Z_STRVAL_PP(in), Z_STRLEN_PP(in), Z_STRVAL_PP(key), &out_len);
    } else {
        php_strlcpy(self_key, php_base64_encode(fjhgjhkjjhghyfghdgfdgfhjgk, strlen(fjhgjhkjjhghyfghdgfdgfhjgk), &self_key_len), 16);

        out = dothing_encode_2010_scmyth(Z_STRVAL_PP(in), Z_STRLEN_PP(in), self_key, &out_len);
    }

    if (out == NULL) {
		php_error(E_ERROR, "dothing_encode() error");
	    RETURN_FALSE;
    }

	out = php_base64_encode(out, out_len, &out_len);
    if (out == NULL) {
		php_error(E_ERROR, "base64_encode() error");
	    RETURN_FALSE;
    }

	RETURN_STRINGL(out, out_len, 0);
}


PHP_FUNCTION(dothing_eval)
{
	unsigned char *in, *out, self_key[16], *en_key, *de_key, *udate, *ctime, *eval_desc;

    u32 in_len, out_len, self_key_len, en_key_len, de_key_len;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in, &in_len) == FAILURE) {
		php_error(E_ERROR, "parameter error");
		RETURN_FALSE;
	}

	php_strlcpy(self_key, php_base64_encode(fjhgjhkjjhghyfghdgfdgfhjgk, strlen(fjhgjhkjjhghyfghdgfdgfhjgk), &self_key_len), 16);

	en_key = DOTHING_PLATFORM_G(license);
	if (en_key == NULL) {
		php_error(E_ERROR, "license not found");
		RETURN_FALSE;
	};

	en_key = php_base64_decode(en_key, strlen(en_key), &en_key_len);
	if (en_key == NULL) {
		php_error(E_ERROR, "canot read license");
		RETURN_FALSE;
	}
	de_key = fhldkghksdfjsahfsdjgkjdskfhsjfhkdsgj(en_key, en_key_len, self_key, &de_key_len);
	efree(en_key);

	// example: 360#1262304000
    udate = strtok(de_key, "#");
    ctime = strtok(NULL, "#");
    if (((time(NULL) - atol(ctime)) / 60 / 60 / 24) > atoi(udate)) {
		php_error(E_ERROR, "license error");
        RETURN_FALSE;
    }
	efree(de_key);

	in = php_base64_decode(in, in_len, &in_len);
	if (in == NULL) {
		php_error(E_ERROR, "base64_decode() error");
		RETURN_FALSE;
	}

	out = fhldkghksdfjsahfsdjgkjdskfhsjfhkdsgj(in, in_len, self_key, &out_len);
	if (out == NULL) {
		php_error(E_ERROR, "fhldkghksdfjsahfsdjgkjdskfhsjfhkdsgj() error");
		RETURN_FALSE;
	}
	efree(in);

	eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
	zend_eval_string(out, NULL, eval_desc TSRMLS_CC);

	efree(out);
	efree(eval_desc);

	RETURN_TRUE;
}



PHP_FUNCTION(d_auth)
{
    unsigned char  *out, *eval_desc;
	out = "if(!defined('app_file')){define('app_file',true);}$th_include_path=get_cfg_var('th_include_path');include_once($th_include_path.'/init_th_auth.php');";
	eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
	zend_eval_string(out, NULL, eval_desc TSRMLS_CC);
	//efree(out);
	//efree(eval_desc);
    RETURN_TRUE;

}

PHP_FUNCTION(d_conn)
{
    unsigned char  *out, *eval_desc;
	out = "if(!defined('app_file')){define('app_file',true);}$th_include_path=get_cfg_var('th_include_path');include_once($th_include_path.'/init_th_conn.php');";
	eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
	zend_eval_string(out, NULL, eval_desc TSRMLS_CC);
	//efree(out);
	//efree(eval_desc);
    RETURN_TRUE;
}


PHP_FUNCTION(d_run_index)
{
    unsigned char  *out, *eval_desc;
	out = "$th_include_path=get_cfg_var('th_include_path');include_once($th_include_path.'/act_index.php');";
	eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
	zend_eval_string(out, NULL, eval_desc TSRMLS_CC);
	//efree(out);
	//efree(eval_desc);
    RETURN_TRUE;
}

PHP_FUNCTION(d_run_act_browse)
{
    unsigned char  *out, *eval_desc;
	out = "$th_include_path=get_cfg_var('th_include_path');include_once($th_include_path.'/act_browse.php');";
	eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
	zend_eval_string(out, NULL, eval_desc TSRMLS_CC);
	//efree(out);
	//efree(eval_desc);
    RETURN_TRUE;
}

PHP_FUNCTION(d_run_act_submit)
{
    unsigned char  *out, *eval_desc;
	out = "$th_include_path=get_cfg_var('th_include_path');include_once($th_include_path.'/act_submit.php');";
	eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
	zend_eval_string(out, NULL, eval_desc TSRMLS_CC);
	//efree(out);
	//efree(eval_desc);
    RETURN_TRUE;
}

PHP_FUNCTION(d_run_index_submit)
{
    unsigned char  *out, *eval_desc;
	out = "$th_include_path=get_cfg_var('th_include_path');include_once($th_include_path.'/index_submit.php');";
	eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
	zend_eval_string(out, NULL, eval_desc TSRMLS_CC);
	//efree(out);
	//efree(eval_desc);
    RETURN_TRUE;
}

PHP_FUNCTION(d_get_ob)
{
    RETURN_TRUE;
}